#!/bin/bash

BLKON=test/online
BLKOFF=test/offline

LVM_ON=/dev/mapper/docker-fio--test
LVM_OFF=/dev/mapper/docker-iocost_offline

DIRON=/export/iocost_online
DIROFF=/export/iocost_offline

READ_ONLINE="8:16 104857600"
WRITE_ONLINE="8:16 104857600"

#READ_ONLINE="8:0 41943040"
#WRITE_ONLINE="8:0 41943040"

function disable_read_ahead()
{
  dev=$1
  if [ -n "${dev}" ]; then
    NUM=$(lsblk -no MAJ:MIN ${dev})
    d=$(echo $NUM)
    echo 0 > /sys/class/bdi/${d}/read_ahead_kb
  else
    echo "no device specified, do nothing."
  fi
}

function run_fio()
{
  local rw=$1
  local direct=$2

  echo "start test ...."
  date

  cgexec -g memory,blkio:${BLKON} fio -directory=${DIRON} -direct=${direct} -iodepth=1 -thread -rw=${rw} -ioengine=libaio -bs=16k -size=1G -numjobs=8 -group_reporting -time_based=1 -runtime=12000 -name=mytest_online &> online-${rw}.log &

  #cgexec -g blkio:${BLKOFF} fio -directory=${DIROFF} -direct=${direct} -iodepth=1 -thread -rw=${rw} -ioengine=psync -bs=16k -size=1G -numjobs=16 -group_reporting -time_based=1 -runtime=12000 -name=mytest_offline &> offline-${rw}.log &
}

function fio_direct_seq_write()
{
  echo "run fio test (direct seq write)"
  run_fio write 1
}

function fio_direct_rand_write()
{
  echo "run fio test (direct rand write)"
  run_fio randwrite 1
}

function fio_direct_seq_read()
{
  echo "run fio test (direct seq read)"
  run_fio read 1
}

function fio_direct_rand_read()
{
  echo "run fio test (direct rand read)"
  run_fio randread 1
}

function fio_buffer_seq_write()
{
  echo "run fio test (buffer seq write)"
  run_fio write 0
}

function fio_buffer_rand_write()
{
  echo "run fio test (buffer rand write)"
  run_fio randwrite 0
}

function fio_buffer_seq_read()
{
  echo "clean cache and disbale readahead"
  echo 1 > /proc/sys/vm/drop_caches
  echo "run fio test (buffer seq read)"
  run_fio read 0
}

function fio_buffer_rand_read()
{
  echo "clean cache and disbale readahead"
  echo 1 > /proc/sys/vm/drop_caches
  echo "run fio test (buffer rand read)"
  run_fio randread 0
}

function set_read()
{

echo "set blkio throttle"
echo "set online read limit to ${READ_ONLINE}"
cgset -r blkio.throttle.read_bps_device="${READ_ONLINE}" ${BLKON}

}

function set_write()
{

echo "set blkio throttle"
echo "set online write limit to ${WRITE_ONLINE}"
cgset -r blkio.throttle.write_bps_device="${WRITE_ONLINE}" ${BLKON}

}

############################################################### main start ####################################################

if [ $# -lt 1 ]; then
  usage
  exit 1
fi

umount ${DIRON}
r=$(mount | grep 'on /export/iocost_' -c)
if [ $r -ne 2 ]; then
  echo "making filesystem ..."
  #mkfs.ext4 -E lazy_journal_init=0,lazy_itable_init=0 -D -F ${LVM_ON}
  mkfs.ext4 -E lazy_itable_init=0 -D -F ${LVM_ON}
  echo "mount lvm ..."
  mount ${LVM_ON} ${DIRON}
  echo "umount lvm .."
  umount ${DIRON}
  mount ${LVM_ON} ${DIRON}
fi

echo "setup cgroups"
if [ ! -e /sys/fs/cgroup/cpu/${BLKON} ];then
   cgcreate -g cpu:${BLKON}
fi

if [ ! -e /sys/fs/cgroup/cpu/${BLKOFF} ];then
   cgcreate -g cpu:${BLKOFF}
fi


if [ ! -e /sys/fs/cgroup/blkio/${BLKON} ];then
   cgcreate -g blkio:${BLKON}
fi

if [ ! -e /sys/fs/cgroup/blkio/${BLKOFF} ];then
   cgcreate -g blkio:${BLKOFF}
fi

if [ ! -e /sys/fs/cgroup/memory/${BLKON} ];then
   cgcreate -g memory:${BLKON}
fi

if [ ! -e /sys/fs/cgroup/memory/${BLKOFF} ];then
   cgcreate -g memory:${BLKOFF}
fi

echo "set memory limit"
cgset -r memory.limit_in_bytes=$((1024 * 1024 * 1024 * 10)) ${BLKON}
cgset -r memory.limit_in_bytes=$((1024 * 1024 * 1024 * 10)) ${BLKOFF}

echo "set cpu limit"
cgset -r cpu.cfs_quota_us=800000 ${BLKON}
cgset -r cpu.cfs_quota_us=800000 ${BLKOFF}

case $1 in 
    "dr")
        set_read
        fio_direct_seq_read
	;;
    "dw")
	set_write
        fio_direct_seq_write
	;;
    "br")
        set_read
	fio_buffer_seq_read
	;;
    "bw")
	set_write
	fio_buffer_seq_write
	;;
    "drr")
        set_read
        fio_direct_rand_read
	;;
    "drw")
	set_write
        fio_direct_rand_write
	;;
    "brr")
        set_read
	fio_buffer_rand_read
	;;
    "brw")
	set_write
	fio_buffer_rand_write
	;;
     *)
	usage
	;;
esac
